/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package Wires.impl;

import java.io.File;
import java.util.UUID;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.m2m.atl.engine.AtlEMFModelHandler;
import org.eclipse.m2m.atl.engine.vm.nativelib.ASMModel;

import Wires.AtomicModelTransformation;
import Wires.CompositeTransformation;
import Wires.ConnectableElement;
import Wires.GenericTransformation;
import Wires.IdentityTransformation;
import Wires.InputFormalParameter;
import Wires.Model;
import Wires.OutputActualParameter;
import Wires.TypeParameter;
import Wires.WiresPackage;
import Wires.exep.ResourceNotFoundException;
import Wires.exep.TypeNotFoundException;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Type Parameter</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * </p>
 *
 * @generated
 */
public class TypeParameterImpl extends ActualParameterImpl implements TypeParameter {
	/***************************************************/
	/***************** Modifications *******************/
	
	private Boolean active = false;
	
	public void setActive(Boolean active) {
		this.active = active;
	}

	public Boolean getActive() {
		return active;
	}

	public void loadModel(){
		String modelName = this.getType().getName();
		AtlEMFModelHandler modelHandler = (AtlEMFModelHandler) AtlEMFModelHandler.getDefault(AtlEMFModelHandler.AMH_EMF);
		this.model =  modelHandler.loadModel(modelName, this.metamodel, URI.createFileURI(this.modelPath));
	}
	
	public void execute(ConnectableElement incoming) throws Exception{
		//Load the model and the metamodel
		
		if (incoming instanceof Model){
			
			if (((Model)incoming).getPath() == null || ((Model)incoming).getPath().equals(""))
				throw new ResourceNotFoundException(incoming);
			
			//Save the model path
			this.modelPath = ((Model)incoming).getPath();
			//Load the model if it is not an instance of IdentityTransformation
			if (!(this.eContainer() instanceof IdentityTransformation)){
				this.loadMetamodel();
				this.loadModel();
			}
			this.setActive(true);
			
		}else if (incoming instanceof OutputActualParameter){
			//IdentityTransformation OutputParameter to TypeParameter
			if (((OutputActualParameter) incoming).eContainer() instanceof AtomicModelTransformation
					|| ((OutputActualParameter) incoming).eContainer() instanceof GenericTransformation
					|| ((OutputActualParameter) incoming).eContainer() instanceof CompositeTransformation
					|| ((OutputActualParameter) incoming).eContainer() instanceof IdentityTransformation){
				if (((OutputActualParameter) incoming).getType() == null)
					throw new TypeNotFoundException(incoming);
				
				this.type = ((OutputActualParameter) incoming).getType();
				this.copyASMModel(((OutputActualParameterImpl)incoming).getModel());				
			}else if (incoming instanceof InputFormalParameter){
				this.copyASMModel(((InputFormalParameterImpl)incoming).getModel());
			}
			this.setActive(true);
		}
		
		((ConnectableElementImpl)this.eContainer()).execute(incoming);		
	}
	
	private void copyASMModel(ASMModel model){
		//Copy the out parameter model on this input parameter
//		AtlEMFModelHandler modelHandler = (AtlEMFModelHandler) AtlEMFModelHandler.getDefault(AtlEMFModelHandler.AMH_EMF);
//		modelHandler.saveModel(model, model.getName(), false);
//		this.modelPath = model.getName();	
		
		String name = "tmp" + UUID.randomUUID().toString();
		AtlEMFModelHandler modelHandler = (AtlEMFModelHandler)AtlEMFModelHandler.getDefault("EMF");
		modelHandler.saveModel(model, name, false);
		this.modelPath = name;

		
		this.loadMetamodel();
		this.loadModel();		
		
//		File f = new File(model.getName());
		File f = new File(name);
		f.delete();
	}
	
	/**************** Modifications End ****************/
	/***************************************************/
	
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected TypeParameterImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return WiresPackage.Literals.TYPE_PARAMETER;
	}

} //TypeParameterImpl
